

module inst_rom0 ( doa, addra, clka );
    output [15:0] doa;
    input  [12:0] addra;
    input  clka;

    reg [15:0] mem[0:2047];
    reg [10:0] addr;
    reg [15:0] data_out;

    always @(negedge clka) begin
        addr <= addra;
    end

    always @(posedge clka) begin
        data_out <= mem[addr];
    end

    assign doa = data_out;

endmodule

module inst_rom1 ( doa, addra, clka );
    output [15:0] doa;
    input  [12:0] addra;
    input  clka;

    reg [15:0] mem[0:2047];
    reg [10:0] addr;
    reg [15:0] data_out;

    always @(negedge clka) begin
        addr <= addra;
    end

    always @(posedge clka) begin
        data_out <= mem[addr];
    end

    assign doa = data_out;

endmodule

module data_ram0 ( doa, dia, addra, cea, clka, wea);
    parameter DATA_WIDTH_A = 8; 
    parameter ADDR_WIDTH_A = 12;
    parameter DATA_DEPTH_A = 4096;

    output [DATA_WIDTH_A-1:0] doa;

    input  [DATA_WIDTH_A-1:0] dia;
    input  [ADDR_WIDTH_A-1:0] addra;
    input  wea;
    input  cea;
    input  clka;

    reg [7:0] mem[0:4095];
    reg [11:0] addr;
    reg [7:0] data_out;

    always @(negedge clka) begin
        addr <= addra;
        if (wea) begin
            mem[addra] <= dia;
        end
    end

    always @(posedge clka) begin
        if (cea) begin
            if (wea) begin
                data_out <= 8'hzz;
            end else begin
                data_out <= mem[addr];
            end
        end
    end

    assign doa = data_out;
endmodule

module data_ram1 ( doa, dia, addra, cea, clka, wea);
    parameter DATA_WIDTH_A = 8; 
    parameter ADDR_WIDTH_A = 12;
    parameter DATA_DEPTH_A = 4096;

    output [DATA_WIDTH_A-1:0] doa;

    input  [DATA_WIDTH_A-1:0] dia;
    input  [ADDR_WIDTH_A-1:0] addra;
    input  wea;
    input  cea;
    input  clka;

    reg [7:0] mem[0:4095];
    reg [11:0] addr;
    reg [7:0] data_out;

    always @(negedge clka) begin
        addr <= addra;
        if (wea) begin
            mem[addra] <= dia;
        end
    end

    always @(posedge clka) begin
        if (cea) begin
            if (wea) begin
                data_out <= 8'hzz;
            end else begin
                data_out <= mem[addr];
            end
        end
    end

    assign doa = data_out;
endmodule
module data_ram2 ( doa, dia, addra, cea, clka, wea);
    parameter DATA_WIDTH_A = 8; 
    parameter ADDR_WIDTH_A = 12;
    parameter DATA_DEPTH_A = 4096;

    output [DATA_WIDTH_A-1:0] doa;

    input  [DATA_WIDTH_A-1:0] dia;
    input  [ADDR_WIDTH_A-1:0] addra;
    input  wea;
    input  cea;
    input  clka;

    reg [7:0] mem[0:4095];
    reg [11:0] addr;
    reg [7:0] data_out;

    always @(negedge clka) begin
        addr <= addra;
        if (wea) begin
            mem[addra] <= dia;
        end
    end

    always @(posedge clka) begin
        if (cea) begin
            if (wea) begin
                data_out <= 8'hzz;
            end else begin
                data_out <= mem[addr];
            end
        end
    end

    assign doa = data_out;
endmodule
module data_ram3 ( doa, dia, addra, cea, clka, wea);
    parameter DATA_WIDTH_A = 8; 
    parameter ADDR_WIDTH_A = 12;
    parameter DATA_DEPTH_A = 4096;

    output [DATA_WIDTH_A-1:0] doa;

    input  [DATA_WIDTH_A-1:0] dia;
    input  [ADDR_WIDTH_A-1:0] addra;
    input  wea;
    input  cea;
    input  clka;

    reg [7:0] mem[0:4095];
    reg [11:0] addr;
    reg [7:0] data_out;

    always @(negedge clka) begin
        addr <= addra;
        if (wea) begin
            mem[addra] <= dia;
        end
    end

    always @(posedge clka) begin
        if (cea) begin
            if (wea) begin
                data_out <= 8'hzz;
            end else begin
                data_out <= mem[addr];
            end
        end
    end

    assign doa = data_out;
endmodule

